﻿using System;
using System.Configuration;
using System.Linq;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Medianamik.Core;
using Medianamik.Core.Configuration;
using Medianamik.Core.Sugar;
using Medianamik.Core.Urls;
using Medianamik.Globalization;
using Telerik.Web.UI;
using Telerik.Web.UI.Editor.DialogControls;
using System.Globalization;

namespace Medianamik.UI.Controls
{
    /// <summary>
    /// Contrôle permettant de choisir un fichier
    /// </summary>
    public class PathPicker : BaseMedianamikControl, IScriptControl
    {
        private RadDialogOpener opener;
        private TextBox pathTextBox;
        private HiddenField hiddenPathField;
        private FileManagerDialogParameters documentManagerParameters;
        private static readonly MedianamikConfigSection Config = (MedianamikConfigSection)ConfigurationManager.
            GetSection(ConfigurationSectionName.MEDIANAMIK);
        DialogDefinition documentManager;
        private static readonly string[] DefaultDocumentPaths = new[] { Config.PathPickerFilesPath };
        private HashSet<string> _documentPaths;
        protected HashSet<string> DocumentPaths
        {
            get
            {
                if (_documentPaths == null)
                {
                    string[] documentFilesPath;
                    if (CurrentSite == null || string.IsNullOrEmpty(CurrentSite.RootFilesPath))
                    {
                        documentFilesPath = DefaultDocumentPaths;
                    }
                    else
                    {
                        documentFilesPath = new[] { CurrentSite.RootFilesPath };
                    }

                    _documentPaths = new HashSet<string>(documentFilesPath);
                }
                return _documentPaths;
            }
        }

        public int MaxUploadFileSize
        {
            get
            {
                return Config.EditorMaxUploadFileSize;
            }
        }

        public virtual void AddPath(string path)
        {
            DocumentPaths.Add(path);
        }

        public virtual void RemovePath(string path)
        {
            DocumentPaths.Remove(path);
        }

        protected override void CreateControlHierarchy(bool pUseDataSource)
        {
            opener = new RadDialogOpener();
            pathTextBox = new TextBox { CssClass = "TxtBox" };
            hiddenPathField = new HiddenField();
            documentManagerParameters = new FileManagerDialogParameters();
            var imgOpenDocumentManager = new Image { ID = "OpenDocumentManagerButton" };
            var imgOpenMedianamikLink = new Image();
            var imgDelete = new Image();

            Controls.Add(opener);
            Controls.Add(pathTextBox);
            Controls.Add(hiddenPathField);
            Controls.Add(imgOpenDocumentManager);
            Controls.Add(new LiteralControl("&nbsp;"));
            Controls.Add(imgOpenMedianamikLink);
            Controls.Add(new LiteralControl("&nbsp;"));
            Controls.Add(imgDelete);

            opener.ID = "opener";
            opener.EnableEmbeddedSkins = Skins.DEFAULT_USE_EMBEDDED_SKIN;
            opener.Skin = Skins.DEFAULT_SKIN;
            pathTextBox.ID = ControlToValidateId;

            imgOpenDocumentManager.ImageUrl = "/medianamik/images/icones/ico_repertoire.gif";
            imgOpenDocumentManager.CssClass = "IconePathPicker";
            imgOpenDocumentManager.AlternateText = Translator.Translate("medianamik_controls",
                "open_patchpicker");
            imgOpenDocumentManager.Attributes.Add("onclick",
                string.Format("$find('{0}').openDocManager();return false;", ClientID));

            imgOpenMedianamikLink.ImageUrl = "/medianamik/images/icones/ico_medianamiklink.gif";
            imgOpenMedianamikLink.CssClass = "IconePathPicker";
            imgOpenMedianamikLink.AlternateText = Translator.Translate("medianamik_controls",
                "open_medianamik_link_picker");
            imgOpenMedianamikLink.Attributes.Add("onclick",
                string.Format("$find('{0}').openMedianamikLinkWindow();", ClientID));

            imgDelete.ImageUrl = "/medianamik/images/Icones/Ico_Supprimer.gif";
            imgDelete.CssClass = "IconePathPicker";
            imgDelete.AlternateText = Translator.Translate("medianamik_controls",
                "delete_linkpicker_content");
            imgDelete.Attributes.Add("onclick", string.Format("$find('{0}').clear();", ClientID));

            documentManagerParameters.ViewPaths = DocumentPaths.ToArray();
            documentManagerParameters.UploadPaths = DocumentPaths.ToArray();
            documentManagerParameters.DeletePaths = DocumentPaths.ToArray();
            documentManagerParameters.MaxUploadFileSize = MaxUploadFileSize;
            documentManagerParameters.SearchPatterns = new[] { "*.*" };
            documentManagerParameters["Language"] = CultureInfo.CurrentCulture.Name;
            documentManager = new DialogDefinition(typeof(DocumentManagerDialog),
                documentManagerParameters)
            {
                Width = Unit.Pixel(694),
                Height = Unit.Pixel(440),
                ClientCallbackFunction =
                    String.Format(
                    "Function.createDelegate($find('{0}'), $find('{0}').documentManagerCallBack)",
                    ClientID)
            };

            opener.DialogDefinitions.Add("DocumentManager", documentManager);

            ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference("/Medianamik/Services/UrlsService.asmx"));

            if (pUseDataSource)
            {
                pathTextBox.Width = ControlInfo.Width.HasValue ? ControlInfo.Width.Value : WIDTH;
                var value = (DataSource == null) ? String.Empty : DataSource.ToString();

                bool disabled;
                var resolver = new LinkResolver(MedianamikContext.Current.EditionCulture,
                                                new ObjectFactory<IUrlDictionary>().Get());

                //PL : Essai d'adaptation du code pour être backward compatible
                //Ne pas ajouter de \" dans l'expression ci bas car il ajoutera un " dans le résultat
                //if (resolver.IsEncodedLink(value))

                var result = resolver.Resolve("href=\"" + value, out disabled);

                if (disabled)
                {
                    pathTextBox.Text = result.Substring(6);
                    hiddenPathField.Value = value;
                    pathTextBox.CssClass += " ReadOnly";
                    pathTextBox.Attributes.Add("title", pathTextBox.Text);
                    pathTextBox.Attributes.Add("onfocus", "this.blur();");
                }
                else
                {
                    pathTextBox.Text = value;
                }
            }

            opener.DialogsCssFile = "/Medianamik/includes/medianamik.css?v=" +
                    Utility.GetFileVersion();
        }

        protected override void OnPreRender(EventArgs e)
        {
            if (!DesignMode)
            {
                // Test for ScriptManager and register if it exists
                var sm = ScriptManager.GetCurrent(Page);
                if (sm == null)
                {
                    throw new Exception("A ScriptManager control must exist on the current page.");
                }
                sm.RegisterScriptControl(this);
            }
            base.OnPreRender(e);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            if (!DesignMode)
            {
                var sm = ScriptManager.GetCurrent(Page);
                sm.RegisterScriptDescriptors(this);
            }
            base.Render(writer);
        }

        public override Type TypeOfValue
        {
            get { return typeof(string); }
        }

        public override object GetValue()
        {
            EnsureChildControls();

            if (RegularExpressions.MedianamikLink
                .IsMatch(HttpUtility.UrlDecode("href=\"" + hiddenPathField.Value)))
            {
                //Il s'agit d'un Guid
                return hiddenPathField.Value;
            }

            //Dans ce cas on préfère prendre la valeur du textbox car elle a pu être modifiée.
            return pathTextBox.Text;
        }

        public override void SetValue(object value)
        {
            EnsureChildControls();
            pathTextBox.Text = value == null ? null : value.ToString();
        }

        public string Path
        {
            get
            {
                return GetValue().ToString();
            }
        }

        protected override bool WrapContentInParagraph
        {
            get
            {
                return false;
            }
        }

        public IEnumerable<ScriptDescriptor> GetScriptDescriptors()
        {
            var descriptor = new ScriptControlDescriptor("Medianamik.PathPicker", ClientID);
            descriptor.AddElementProperty("pathTextBox", pathTextBox.ClientID);
            descriptor.AddElementProperty("hiddenPathField", hiddenPathField.ClientID);
            descriptor.AddProperty("editionCultureName", MedianamikContext.Current.EditionCulture.Name);
            descriptor.AddProperty("linkPickerWindowTitle", Translator.Translate("Medianamik_ContentManagement", "MedianamikLinkWindowTitle"));
            descriptor.AddComponentProperty("opener", opener.ClientID);
            return new ScriptDescriptor[] { descriptor };
        }

        public IEnumerable<ScriptReference> GetScriptReferences()
        {
            var reference = new ScriptReference
            {
                Path =
                    Resources.GetWebResourceUrl("Scripts.PathPicker.js", Page,
                                                typeof(PathPicker), typeof(PathPicker).Assembly)
            };
            return new[] { reference };
        }
    }
}